package net.chromedpork.hypertext.filtration;



import java.util.ArrayList;
import java.util.List;

import org.htmlcleaner.TagNode;
import org.htmlcleaner.XPatherException;

import net.chromedpork.hypertext.validation.Assertion;



/**
 *
 *  List filter object.
 *
 *  @author Inode <inode@chromedpork.net>
 *
 */

public class ListFilterObject implements Filter
{
    private final String elementXPath;
    private final String returnAttribute;



    /**
     *
     *  Constructs a list filter object with preconfigured element
     *  XPath expression field.
     *
     *  @param elementXPath     XPath expression to enumerate element data
     *
     */

    ListFilterObject(String elementXPath)
    {
        Assertion.notNull(elementXPath, "element XPath is null");

        this.elementXPath    = elementXPath;
        this.returnAttribute = null;
    }



    /**
     *
     *  Constructs a list filter object with preconfigured element
     *  XPath expression field, plus an indicator to return the value of a
     *  tag attribute once XPath expressions have been evaluated.
     *
     *  @param elementXPath     XPath expression to enumerate element datadata
     *  @param returnAttribute  name of tag attribute whose value is required
     *
     */

    ListFilterObject(String elementXPath, String returnAttribute)
    {
        Assertion.notNull(elementXPath, "element XPath is null");
        Assertion.notNull(returnAttribute, "return attribute is null");

        this.elementXPath    = elementXPath;
        this.returnAttribute = returnAttribute;
    }
    


    /**
     *
     *  Parses a tree of TagNodes, and generates a List of resultant data
     *  strings from the evaluation of the element XPath expression against
     *  the tree.
     *
     *  @param root     root node of the desired tag hierarchy.
     *
     *  @return result List
     *
     *  @throws FilterException
     *
     */
    
    public List<String> parse(TagNode root) throws FilterException
    {
        Assertion.notNull(root, "tag root is null");

        
        List<String> result = new ArrayList<String>();
        
        Object[] elements = null;

        
        try
        {
            elements = root.evaluateXPath(elementXPath);
        }

        catch (XPatherException exception)
        {
            throw new FilterException(exception.getMessage());
        }


        for (int index = 0; index < elements.length; index++)
        {
            String element;
            
            if (returnAttribute != null)
            {
                TagNode elementNode = (TagNode)elements[index];
                element = elementNode.getAttributeByName(returnAttribute);
            }

            else
            {
                TagNode elementNode = (TagNode)elements[index];
                element = elementNode.getText().toString();
            }

            result.add(element);
        }


        return (result);
    }
}
